#!/user/bin/env python3
# -*- coding: utf-8 -*-
"""
--------------------------------------
    Author:     JiChao_Song
    Date  :     2021/12/17 16:25
    Desc  :
--------------------------------------
"""
from django.urls import path
from django.utils.decorators import method_decorator
from django_http_log.common.request import BaseAPIView
from django_http_log.common.response import SuccessResponse, SystemExceptionResponse, CommonResponse, \
    ParamsErrorResponse

from common.decorator.token_decorator import isAuthentication
from common.enums.person_enums import MenuTypeEnum, MenuStatusEnum
from common.enums.response_enums import CommonResultEnums
from common.utils.log_utils import logger
from common.utils.other_utils import get_time, queryDict
from common.utils.token_utils import RequestAuthTokenUtil
from person.models import Menu
from person.serializers.menu import MenuSerializer, MenuArraySerializer, MenuParentCodeListSerializer
from platform_auth.settings import APIDOC_DECORATOR
from django.db import transaction, connection


class MenuBaseAPIView(BaseAPIView):
    Model = Menu

    serializer_class = MenuSerializer


class MenuAddAPIView(MenuBaseAPIView):
    """
    菜单新增
    """

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/add', summary = '菜单新增')
    @APIDOC_DECORATOR.ApiParams(value = 'name', require = True, type = 'string', desc = '菜单名称')
    @APIDOC_DECORATOR.ApiParams(value = 'code', require = True, type = 'int', desc = '权限code')
    @APIDOC_DECORATOR.ApiParams(value = 'type', type = 'int', require = True, desc = '类型')
    @APIDOC_DECORATOR.ApiParams(value = 'parentCode', type = 'int', desc = '父级code')
    @APIDOC_DECORATOR.ApiParams(value = 'remark', type = 'string', desc = '备注')
    @method_decorator(isAuthentication(flag = True))
    def post(self, request, *args, **kwargs):
        try:
            body: dict = request.data.copy()
            userId, userName = RequestAuthTokenUtil(request = request).get_user_id_and_username()

            # 1. 判断code是否存在
            queryset_code = self.Model.objects.filter(code = body.get('code'), deleted = False)
            if queryset_code.count() != 0:
                return CommonResponse(codeEnums = CommonResultEnums.MENU_CODE_IS_EXIST)
            # 2. 判断parentCode是否存在
            queryset_parent_code = self.Model.objects.filter(id = body.get('parentCode'), deleted = False)

            if body.get('parentCode') and body.get('parentCode') != '':
                if queryset_parent_code.count() == 0:
                    return CommonResponse(codeEnums = CommonResultEnums.MENU_PARENT_CODE_IS_NOT_EXIST)

            # 3. 保存
            with transaction.atomic():
                menu_data = self.Model.objects.create(
                    name = body.get('name'),
                    code = body.get('code'),
                    parentCode = queryset_parent_code.first(),
                    type = body.get('type'),
                    remark = body.get('remark'),
                    creatorId = userId,
                    creatorName = userName,
                )
            # 4. 序列化
            serializer = self.serializer_class(menu_data, exclude = self.exclude_fields)

            return SuccessResponse(result = serializer.data)

        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


class MenuListAPIView(MenuBaseAPIView):
    serializer_class = MenuArraySerializer

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/list', summary = '菜单列表')
    @method_decorator(isAuthentication(flag = True))
    def post(self, request, *args, **kwargs):
        try:
            queryset = self.Model.objects.filter(parentCode = None, type = MenuTypeEnum.FIRST_MENU.key,
                                                 deleted = False)

            serializer = self.serializer_class(queryset, many = True, exclude = self.exclude_fields)

            return SuccessResponse(result = {'list': serializer.data})
        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


class MenuEditAPIView(MenuBaseAPIView):
    """
    菜单新增
    """

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/edit', summary = '菜单编辑')
    @APIDOC_DECORATOR.ApiParams(value = 'menuId', type = 'int', require = True, desc = '菜单Id')
    @APIDOC_DECORATOR.ApiParams(value = 'name', type = 'string', require = True, desc = '菜单名称')
    @APIDOC_DECORATOR.ApiParams(value = 'parentCode', type = 'int', desc = '父级code')
    @APIDOC_DECORATOR.ApiParams(value = 'remark', type = 'string', desc = '备注')
    @method_decorator(isAuthentication(flag = True))
    def post(self, request, *args, **kwargs):
        try:
            body: dict = request.data.copy()
            userId, userName = RequestAuthTokenUtil(request = request).get_user_id_and_username()

            # 1. 根据menuId判断菜单是否存在
            queryset_id = self.Model.objects.filter(id = body.get('menuId'), deleted = False)
            if queryset_id.count() == 0:
                return CommonResponse(codeEnums = CommonResultEnums.MENU_ID_IS_NOT_EXIST)
            # 2. 判断parentCode是否存在
            if body.get('parentCode') and body.get('parentCode') != '':
                queryset_parent_code = self.Model.objects.filter(id = body.get('parentCode'), deleted = False)
                if queryset_parent_code.count() == 0:
                    return CommonResponse(codeEnums = CommonResultEnums.MENU_PARENT_CODE_IS_NOT_EXIST)
            # 3. 更新
            with transaction.atomic():
                queryset_id.update(
                    name = body.get('name'),
                    parentCode = body.get('parentCode'),
                    remark = body.get('remark'),
                    updaterId = userId,
                    updaterName = userName,
                    updateTime = get_time(),
                )
            return SuccessResponse()

        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


class MenuDeleteAPIView(MenuBaseAPIView):
    """
    菜单新增
    """

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/delete', summary = '菜单删除')
    @APIDOC_DECORATOR.ApiParams(value = 'menuId', type = 'int', require = True, desc = '菜单Id')
    def post(self, request, *args, **kwargs):
        try:
            body: dict = request.data.copy()
            userId, userName = RequestAuthTokenUtil(request = request).get_user_id_and_username()

            # 1. 根据menuId判断菜单是否存在
            queryset_id = self.Model.objects.filter(id = body.get('menuId'), deleted = False)
            if queryset_id.count() == 0:
                return CommonResponse(codeEnums = CommonResultEnums.MENU_ID_IS_NOT_EXIST)
            # 2. 更新
            with transaction.atomic():
                queryset_id.update(
                    deleted = True,
                    deleteTime = get_time(),
                    updaterId = userId,
                    updaterName = userName,
                    updateTime = get_time(),
                )
            return SuccessResponse()

        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


class MenuParentCodeListAPIView(MenuBaseAPIView):
    serializer_class = MenuParentCodeListSerializer

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/parentCodeList', summary = '菜单列表')
    @method_decorator(isAuthentication(flag = True))
    def post(self, request, *args, **kwargs):
        try:
            queryset = self.Model.objects.filter(parentCode = None, deleted = False)

            serializer = self.serializer_class(queryset, many = True, exclude = self.exclude_fields)

            return SuccessResponse(result = {'list': serializer.data})
        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


class MenuTreeAPIView(MenuBaseAPIView):
    """
    @author:    JiChao_Song
    @desc:      菜单权限设置
    @date:      2021/12/31 16:28
    """
    serializer_class = MenuParentCodeListSerializer

    @APIDOC_DECORATOR.checkParams
    @APIDOC_DECORATOR.start
    @APIDOC_DECORATOR.ApiTag(value = 'menu', desc = '菜单管理')
    @APIDOC_DECORATOR.ApiOperation(method = 'POST', path = '/menu/menuTree', summary = '菜单列表')
    @method_decorator(isAuthentication(flag = True))
    def post(self, request, *args, **kwargs):
        cursor = connection.cursor()

        try:

            queryset = self.Model.objects.raw(
                "SELECT * FROM tmenu WHERE parentCode_id IS NOT NULL AND type IN (102, 103)")
            serializer = self.serializer_class(queryset, many = True, exclude = self.exclude_fields)
            logger.info(queryDict(sql = 'SELECT *, parentCode_id "parentCode" FROM tmenu WHERE parentCode_id IS NOT NULL AND type IN (102, 103)')
                        )
            return SuccessResponse(result = {'list': serializer.data})
        except Exception as e:
            logger.error(e)
            return SystemExceptionResponse()


urlpatterns = [
    path('add', MenuAddAPIView.as_view()),
    path('list', MenuListAPIView.as_view()),
    path('edit', MenuEditAPIView.as_view()),
    path('delete', MenuDeleteAPIView.as_view()),
    path('parentCodeList', MenuParentCodeListAPIView.as_view()),
    path('menuTree', MenuTreeAPIView.as_view()),
]
